home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 12.9 KB | 569 lines | [TEXT/CWIE] |
- /*
- Make QTVR Panorama 1.0b1
-
- A simple PowerPlant application for processing PICT files into QuickTime VR™ movies.
-
- Created 29 Jan 1996 by EGH
-
- Copyright © 1996, Apple Computer, Inc. All rights reserved.
- */
-
- #include <StandardFile.h>
-
- #include <String_Utils.h>
- #include <LCaption.h>
- #include <UDesktop.h>
- #include <UDrawingState.h>
- #include <LEditField.h>
- #include <LGrowZone.h>
- #include <UMemoryMgr.h>
- #include <LPlaceHolder.h>
- #include <URegistrar.h>
- #include <LScroller.h>
- #include <LStdControl.h>
- #include <LTabGroup.h>
- #include <LTextEdit.h>
- #include <LUndoer.h>
- #include <LWindow.h>
- #include <PP_Resources.h>
-
- #include "CApp.h"
-
- #include "CBeachBall.h"
- #include "CMovieMaker.h"
- #include "CPict2VRWindow.h"
- #include "CPrefsWindow.h"
- #include "CUtils.h"
-
- CPreferences *gAppPrefs = nil;
-
- CApp *gApp = nil;
-
- void main(void)
- {
- SetDebugThrow_(debugAction_Alert);
- SetDebugSignal_(debugAction_Alert);
-
- InitializeHeap(8);
- UQDGlobals::InitializeToolbox(&qd);
-
- // check for the existence of QuickTime
- Int32 result;
- OSErr err = ::Gestalt(gestaltQuickTime, &result);
- if (err != noErr)
- {
- ::StopAlert(ALRT_NoQT, nil);
- ExitToShell();
- }
-
- new LGrowZone(20000);
-
- // fire up QuickTime and load the components necessary for
- // creating pano media
- ::EnterMovies();
- ::RegisterComponentResourceFile(CurResFile(), 0);
-
- CApp theApp;
- gApp = &theApp;
- theApp.Run();
-
- ::ExitMovies();
- }
-
-
- CApp::CApp()
- {
- mDropMode = false;
-
- // Register classes for objects created from 'PPob' resources
- URegistrar::RegisterClass(CPict2VRWindow::class_ID, CPict2VRWindow::CreatePict2VRWindowWindowStream);
- URegistrar::RegisterClass(CPrefsWindow::class_ID, CPrefsWindow::CreatePrefsWindowWindowStream);
-
- URegistrar::RegisterClass(LCaption::class_ID, LCaption::CreateCaptionStream);
- URegistrar::RegisterClass(LDialogBox::class_ID, LDialogBox::CreateDialogBoxStream);
- URegistrar::RegisterClass(LEditField::class_ID, LEditField::CreateEditFieldStream);
- URegistrar::RegisterClass(LPicture::class_ID, LPicture::CreatePictureStream);
- URegistrar::RegisterClass(LPlaceHolder::class_ID, LPlaceHolder::CreatePlaceHolderStream);
- URegistrar::RegisterClass(LStdButton::class_ID, LStdButton::CreateStdButtonStream);
- URegistrar::RegisterClass(LStdCheckBox::class_ID, LStdCheckBox::CreateStdCheckBoxStream);
- URegistrar::RegisterClass(LStdControl::class_ID, LStdControl::CreateStdControlStream);
- URegistrar::RegisterClass(LStdPopupMenu::class_ID, LStdPopupMenu::CreateStdPopupMenuStream);
- URegistrar::RegisterClass(LStdRadioButton::class_ID, LStdRadioButton::CreateStdRadioButtonStream);
- URegistrar::RegisterClass(LTabGroup::class_ID, LTabGroup::CreateTabGroupStream);
- URegistrar::RegisterClass(LView::class_ID, LView::CreateViewStream);
- URegistrar::RegisterClass(LWindow::class_ID, LWindow::CreateWindowStream);
-
- // create application preferences
- Str63 appName;
- ::GetIndString(appName, STRx_Standards, str_ProgramName);
- gAppPrefs = new CPreferences('p2vr', Creator_, appName);
-
- // look for preferences and use them
- mPrefsHdl = (P2VRPrefsHdl)gAppPrefs->GetPreferenceResource(ResType_Preferences, 128);
- if (mPrefsHdl == nil)
- {
- // no prefs, so create default ones
- mPrefsHdl = (P2VRPrefsHdl)::NewHandle(sizeof (P2VRPrefsRec));
- if (mPrefsHdl != nil)
- {
- (*mPrefsHdl)->dropMode = mDropMode;
-
- (*mPrefsHdl)->width = 400;
- (*mPrefsHdl)->height = 300;
- (*mPrefsHdl)->codec = 'cvid';
- (*mPrefsHdl)->pan = 0;
- (*mPrefsHdl)->tilt = 0;
- (*mPrefsHdl)->zoom = 0;
- (*mPrefsHdl)->spatialQuality = codecHighQuality;
- (*mPrefsHdl)->depth = 32;
- CopyPStr("\p.tile", (*mPrefsHdl)->tileSuffix);
- CopyPStr("\p.snm", (*mPrefsHdl)->movieSuffix);
-
- (*mPrefsHdl)->replaceFiles = false;
- }
- }
- else
- {
- mDropMode = (*mPrefsHdl)->dropMode;
- }
-
- // initialize spinning cursor
- CBeachBall::InitBeachBall();
-
- if (!mDropMode)
- {
- try
- {
- LWindow *splash = LWindow::CreateWindow(WIND_Splash, this);
-
- if (splash != nil)
- {
- splash->Show();
- splash->UpdatePort();
- UInt32 splashTime = ::TickCount() + 120; // this should be up for at least 180 ticks
- CBeachBall::StartSpinningTask(5);
- while (::TickCount() < splashTime) ;
- CBeachBall::StopSpinningTask();
-
- delete splash;
- }
- }
- catch (...)
- {
- // fall out
- }
- }
- }
-
-
- CApp::~CApp()
- {
- // save the preferences
- if (gAppPrefs != nil && mPrefsHdl != nil)
- {
- (*mPrefsHdl)->dropMode = mDropMode;
- gAppPrefs->SavePreferenceResource(ResType_Preferences, 128, (Handle)mPrefsHdl);
- }
- }
-
-
- Boolean CApp::ObeyCommand(
- CommandT inCommand,
- void *ioParam)
- {
- Boolean cmdHandled = true;
-
- switch (inCommand)
- {
- case cmd_DropMode:
- {
- mDropMode = !mDropMode;
- SetUpdateCommandStatus(true);
- break;
- }
-
- case cmd_Preferences:
- {
- CPrefsWindow *pw = (CPrefsWindow *)LWindow::CreateWindow(WIND_Preferences, this);
- pw->Show();
- break;
- }
-
- default:
- cmdHandled = LDocApplication::ObeyCommand(inCommand, ioParam);
- break;
- }
-
- return cmdHandled;
- }
-
-
- void CApp::FindCommandStatus(
- CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
- outUsesMark = false;
-
- if (sBusy)
- outEnabled = false;
- else
- switch (inCommand)
- {
- case cmd_DropMode:
- outEnabled = true;
- outUsesMark = true;
- outMark = mDropMode ? checkMark:noMark;
- break;
-
- case cmd_Preferences:
- outEnabled = true;
- break;
-
- default:
- LDocApplication::FindCommandStatus(inCommand, outEnabled, outUsesMark,
- outMark, outName);
- break;
- }
- }
-
-
- /* CApp::DoAEOpenOrPrintDoc
-
- Overridden from LDocApplication because we may want to quit afterwards.
- */
- void CApp::DoAEOpenOrPrintDoc(
- const AppleEvent &inAppleEvent,
- AppleEvent& /* outAEReply */,
- Int32 inAENumber)
- {
- AEDescList docList;
- OSErr err = ::AEGetParamDesc(&inAppleEvent, keyDirectObject,
- typeAEList, &docList);
- ThrowIfOSErr_(err);
-
- Int32 numDocs;
- err = ::AECountItems(&docList, &numDocs);
- ThrowIfOSErr_(err);
-
- for (Int32 i = 1; i <= numDocs; i++)
- {
- AEKeyword theKey;
- DescType theType;
- FSSpec theFileSpec;
- Size theSize;
- err = ::AEGetNthPtr(&docList, i, typeFSS, &theKey, &theType,
- (Ptr) &theFileSpec, sizeof(FSSpec), &theSize);
- ThrowIfOSErr_(err);
-
- if (inAENumber == ae_OpenDoc)
- {
- OpenDocument(&theFileSpec);
- }
- else
- {
- // let the user know we don't do printing in this app
- ::StopAlert(ALRT_WeDontPrint, nil);
- }
- }
-
- ::AEDisposeDesc(&docList);
-
- // if we are in drop mode, get outta here
- if (mDropMode)
- DoQuit();
- }
-
-
- void CApp::OpenDocument(
- FSSpec *inMacFSSpec)
- {
- Int16 errStrIndex;
-
- try
- {
- errStrIndex = err_Window;
-
- if (mDropMode && mPrefsHdl != nil)
- {
- // just start making the movie
- MovieMakinRec params;
- params.width = (*mPrefsHdl)->width;
- params.height = (*mPrefsHdl)->height;
- params.srcSpec = *inMacFSSpec;
-
- params.tileSpec = *inMacFSSpec;
- unsigned char charspace = 31 - (*mPrefsHdl)->tileSuffix[0];
- if (params.tileSpec.name[0] > charspace)
- params.tileSpec.name[0] = charspace;
- ConcatPStr(params.tileSpec.name, (*mPrefsHdl)->tileSuffix);
-
- params.destSpec = *inMacFSSpec;
- charspace = 31 - (*mPrefsHdl)->movieSuffix[0];
- if (params.destSpec.name[0] > charspace)
- params.destSpec.name[0] = charspace;
- ConcatPStr(params.destSpec.name, (*mPrefsHdl)->movieSuffix);
-
- params.codec = (*mPrefsHdl)->codec;
- params.spatialQuality = (*mPrefsHdl)->spatialQuality;
- params.depth = (*mPrefsHdl)->depth;
-
- ListenToMessage(msg_MakeMovie, ¶ms);
- }
- else
- {
- // put up a window for editing movie making parameters
- CPict2VRWindow *p2vr = (CPict2VRWindow *)LWindow::CreateWindow(WIND_Pict2VR, this);
- p2vr->AddListener(this);
- p2vr->SetPictFile(inMacFSSpec);
- }
- }
- catch (ExceptionCode err)
- {
- ReportError(err, err_Window);
- }
-
- // drop mode leaves the menu bar inactive
- if (mDropMode)
- UpdateMenus();
- }
-
- void CApp::StartUp()
- {
- ChooseDocument();
- }
-
- void CApp::ChooseDocument()
- {
- StandardFileReply macFileReply;
- SFTypeList typeList;
-
- UDesktop::Deactivate();
- typeList[0] = 'PICT';
- ::StandardGetFile(nil, 1, typeList, &macFileReply);
- UDesktop::Activate();
- if (macFileReply.sfGood)
- {
- OpenDocument(&macFileReply.sfFile);
- }
- }
-
-
- /* CApp::ProgressEvents
-
- An event processing function necessary because the one implemented in
- LApplication does things we dont want such as changing the cursor.
- This one is useful for processing events during lengthy processes
- (and there is a spinning cursor and a modal window in front).
- */
- void CApp::ProgressEvents()
- {
- EventRecord macEvent;
-
- SetUpdateCommandStatus(false);
- Boolean gotEvent;
- Int16 count = 0;
-
- do
- {
- gotEvent = ::WaitNextEvent(everyEvent, &macEvent, 0, mMouseRgnH);
-
- if (LAttachable::ExecuteAttachments(msg_Event, &macEvent))
- {
- if (gotEvent)
- DispatchEvent(macEvent);
- else
- UseIdleTime(macEvent);
- }
-
- LPeriodical::DevoteTimeToRepeaters(macEvent);
-
- if (GetUpdateCommandStatus())
- UpdateMenus();
- } while (gotEvent && ++count < 3); // do not hand over too much time
- }
-
-
- // ======================================
- // constants and statics for movie making
-
- Boolean CApp::sCancelled;
- LWindow *CApp::sProgressWindow = nil;
- Boolean CApp::sBusy = false;
-
- const PaneIDT Button_Stop = 'stop';
- const PaneIDT Caption_Proc = 'proc';
- const PaneIDT Caption_Message = 'mess';
-
- const ResIDT WIND_Progress = 207;
-
- // ======================================
-
- void CApp::ListenToMessage(
- MessageT inMessage,
- void *ioParam)
- {
- switch (inMessage)
- {
- // note: one could conceivably tell the app to make a movie
- // WHILE it is making one. this would work, except that the
- // newly dropped one will be completed before the original is
- // processed. this does not include numbers of PICTs dropped
- // on the app at once in the Finder
- case msg_MakeMovie:
- {
- // the make movie message includes parameters for making the movie
- MovieMakinPtr mmp = (MovieMakinPtr)ioParam;
-
- Str255 procStr;
- ::GetIndString(procStr, STRx_Progress, str_Making);
-
- // create a path name that fits into a Str255 minus the above string
- Str255 moviePathStr;
- GetFullPathName(&mmp->destSpec, moviePathStr, sizeof (Str255) - procStr[0]);
-
- try
- {
- // prepare progress stuff
- sCancelled = false;
- sBusy = true;
- SetUpdateCommandStatus(true);
- UpdateMenus();
- sProgressWindow = LWindow::CreateWindow(WIND_Progress, this);
- ThrowIfNil_(sProgressWindow);
-
- // set the main progress description string
- ConcatPStr(procStr, moviePathStr);
- SetSizedDescriptor(sProgressWindow, Caption_Proc, procStr);
-
- // listen to the stop button - provides both mouse and keyboard
- // initiated user cancellation
- LButton *button;
- button = (LButton *)sProgressWindow->FindPaneByID(Button_Stop);
- if (button != nil)
- button->AddListener(this);
-
- // decide if we are replacing files
- Boolean replaceFiles = false;
- if (mPrefsHdl != nil)
- replaceFiles = (*mPrefsHdl)->replaceFiles;
-
- // finally, make the movie!
- CBeachBall::StartSpinningTask(5);
- Boolean completed = CMovieMaker::MakeAMovie(
- replaceFiles,
- mmp->srcSpec, mmp->tileSpec, mmp->destSpec,
- mmp->width, mmp->height,
- mmp->pan, mmp->tilt, mmp->zoom,
- mmp->codec, mmp->spatialQuality, mmp->depth, MovieProgressProc);
- CBeachBall::StopSpinningTask();
-
- delete sProgressWindow;
- sProgressWindow = nil;
-
- // let the caller know how things went
- mmp->completed = completed;
- }
- catch (ExceptionCode err)
- {
- mmp->completed = false;
-
- // the only exception that can make it here is to fail
- // while creating the progress window
- // all other exceptions are caught by CMovieMaker::MakeAMovie
- if (err != Exception_UserCancelled)
- ReportError(err, err_Window);
- }
-
- sBusy = false;
- UpdateMenus();
- break;
- }
-
- case Button_Stop:
- sCancelled = true;
- break;
- }
- }
-
- /* CApp::MovieProgressProc
-
- Called during processing. Gets events handled, messages displayed and
- user cancellation reported.
- */
- Boolean CApp::MovieProgressProc(
- StringPtr inMessage)
- {
- if (inMessage != nil)
- {
- LPane *messageCaption = sProgressWindow->FindPaneByID(Caption_Message);
- messageCaption->SetDescriptor(inMessage);
- messageCaption->UpdatePort();
- }
-
- gApp->ProgressEvents();
-
- return sCancelled;
- }
-
- /* CApp::BugUserTilSwitchedIn
-
- Use the notification manager to let the user know they should switch in.
- Returns once this has happened.
-
- Useful for waiting to put up alerts during long processes where the possibility
- of the user having switched out is an issue.
- */
- void CApp::BugUserTilSwitchedIn()
- {
- if (!IsOnDuty())
- {
- NMRec note;
- OSErr nmErr;
- Handle sicnH = ::GetResource('SICN', 12000);
-
- if (sicnH)
- {
- ::HNoPurge(sicnH);
- ::DetachResource(sicnH);
- }
-
- note.qType = nmType;
- note.nmMark = 1;
- note.nmIcon = sicnH;
- note.nmSound = (Handle) -1;
- note.nmStr = nil;
- note.nmResp = nil;
- note.nmRefCon = 0;
-
- if ((nmErr = ::NMInstall(¬e)) == noErr)
- {
- while (!IsOnDuty())
- {
- ProgressEvents();
- }
- nmErr = ::NMRemove(¬e);
- }
-
- if (sicnH != nil)
- ::DisposeHandle(sicnH);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-